<template lang="pug">
.form-wrap
    el-form(ref="formLoad" :class="{flex:flex}" :model="ruleForm" :rules="ruleData" :label-width="labelWidth")
        template(v-for="item in formData")
            el-form-item(:label="item.label" :prop="item.prop" :class="{block:item.block,'w100':item.width}"  v-if="item.show !== false")
                .pop-wrap
                    .pop-item(v-for="it in item.pop")
                        .pop-label {{it.label}}
                        .pop-value {{it.value}}
                formItem(
                    :ref="bcFormItemLoad"
                    :type="item.type"
                    :pickerType="item.pickerType"
                    :prop="item.prop"
                    :title="item.title"
                    :option="item.option"
                    :filterable="item.filterable"
                    :remote="item.remote"
                    :remoteMethod="item.remoteMethod"
                    :loading="item.loading"
                    :findStudent="item.findStudent"
                    :optionFn="item.optionFn"
                    :clearable="item.clearable===false?false:true"
                    :clearabled="item.clearabled===false?false:true"
                    :defaultValue="item.defaultValue"
                    :defaultProps="item.defaultProps"
                    :readonly="item.readonly"
                    :disabled="item.disabled"
                    :showCheckbox="item.showCheckbox"
                    :searchShow="item.searchShow"
                    :chooseParent="item.chooseParent"
                    :maxlength="item.maxlength"
                    :max="item.max"
                    :min= "item.min"
                    :editable="item.editable"
                    :tabList="item.tabList"
                    :precision="item.precision"
                    :valueFormat="item.valueFormat"
                    :major="item.major"
                    @handleChange="handleChange"
                    @tabChage="tabChage"
                    :pickerOptions="item.pickerOptions"
                    :placeholder="item.placeholder"
                )
                .pop-r(:title="item.popr" v-show="item.popr") !
</template>
<script  setup>
import formItem from './formItem.vue'
import { deepClone } from '@/utils'
import { emitChangeFn } from 'element-plus'
import { ref, watch, reactive, toRaw } from 'vue'
const prop = defineProps({
    form: {
        type: Array,
        default: function(){
            return []
        }
    },
    flex: { //默认列形式排列
        type: Boolean,
        default: false
    },
    labelWidth: { //默认列形式排列
        type: String,
        default: '110px'
    }
})

let ruleForm = reactive({})
const ruleData = ref({})
const formData = ref([])
let timer


const childRef = ref([])//子组件ref数组列表描述 可以是组件实例或组件名称

const bcFormItemLoad = (el) => {
    childRef.value.push(el)
}
const formInit = () => {
    ruleForm = reactive({})
    ruleData.value = {}
    // formData.value = prop.form
    formData.value.forEach((val) => {
        ruleForm[val.prop] = val.defaultValue || ''
        if(val.rules){
            if(val.rules.constructor == Array){
                val.rules.forEach((item) => {
                    item.trigger = 'change'
                    if(item.required){
                        if(['input', 'textarea', 'inputnumber', 'dbinputnumber', 'password'].includes(val.type)){
                            item.message = '请输入' + val.label
                        }else{
                            item.message = '请选择' + val.label
                        }
                    }
                })
            }else{
                val.rules.trigger = 'change'
                if(val.rules.required){
                    if(['input', 'textarea', 'inputnumber', 'dbinputnumber', 'password'].includes(val.type)){
                        val.rules.message = '请输入' + val.label
                    }else{
                        val.rules.message = '请选择' + val.label
                    }
                }
            }
        }
        ruleData.value[val.prop] = val.rules
    })
    // setTimeout(()=>{
    //     childRef.value.map((val) => {
    //         val.valueInt('')
    //     })
    setTimeout(()=>{
        clear()
    }, 0)
    // }, 0)
}
watch(()=>prop.form, (o, l) => {
    formData.value = o
    formInit()
}, { immediate: true })
const emit = defineEmits(['tabChage', 'handleChange'])
const tabChage = (data) => {
    emit('tabChage')
}
const validateField = (st, fn) => {
    formLoad.value.validateField(st, (valid) => {
        fn && fn(valid)
    })
}
const handleChange = (data) => {
    ruleForm[data.prop] = data.value
    if (data.value && data.value.constructor == Array && (data.value[0] === '' || data.value[1] === '')){
        ruleForm[data.prop] = ''
    }
    formData.value.forEach((val) => {
        if (val.prop == data.prop){
            val.value = data.value
        }
    })
    if (timer){
        clearTimeout(timer)
        timer = null
    }
    timer = setTimeout(()=>{
        if(data.type == 'checkboxall' && data.value.length > 0){
            validateField(data.prop)
        }
        emit('handleChange', toRaw(ruleForm), data)
    }, 10)
}
const formLoad = ref(null)
const validate = (fn) => {
    formLoad.value.validate((valid) => {
        fn && fn(valid, toRaw(ruleForm))
    })
}

const clear = () => {
    formLoad.value.clearValidate()
}
const reset = () => {
    formData.value.forEach((val) => {
        val.defaultValue = ''
    })
    for (let i in ruleForm){
        ruleForm[i] = ''
    }
    setTimeout(()=>{
        clear()
    }, 0)
}
defineExpose({
    clear,
    validateField,
    validate,
    formInit,
    reset
})
</script>
<style lang="less" scoped>
.form-wrap{
    // background-color: #fff;
    width: 100%;
    min-width: 400px;
    .btn-wrap{
        height: 45px;
        margin: 30px 0 20px;
        :deep(button){
            width: 100%;
            height: 100%;
        }
    }
    :deep(.search-box .input-box){
        width: 240px;
        .el-cascader{
            width: 100%;
        }
    }
    :deep(.belongRoles .input-box){
        width: 100% !important;
    }
    .flex{
        display: flex;
        flex-wrap: wrap;
        :deep(.el-form-item){
            // flex-grow: 1;
        }
    }
    :deep(.el-form-item){
            margin-bottom: 16px;
            &.block{
                width: 100%;
                display: flex;
                .search-box .input-box{
                    width: 100%;
                }
            }
        }
}
.pop-wrap{
    position: absolute;
    left: 0;
    top: -24px;
    display: flex;
    font-size: 12px;
    justify-content: center;
    white-space: nowrap;
    .pop-item{
        display: flex;
        align-items: center;
        line-height: 30px;
        margin-right: 5px;
        .pop-label{
            color: red;
        }
        .pop-value{
            color: #666;
        }
    }
}
:deep(.el-form){
    user-select: text;
}
:deep(.el-form-item__error){
    padding-top: 0px;
}
.pop-r{
    height: 15px;
    width: 15px;
    border: 1px solid #999;
    border-radius: 50%;
    text-align: center;
    line-height: 13px;
    margin-left: 5px;
    margin-bottom: 5px;
    color: #999;
}
:deep(.readonly){
    .el-textarea__inner{
        background: transparent;
    }
}
:deep(.el-form-item__content){
    display: block;
}
.w100{
    width: 100%;
    :deep(.input-box){
        width: 100% !important;
    }
}
</style>